<template>
  <div class="markdown-editor" :class="theme">
    <div class="editor-header">
      <h2>Markdown 编辑器</h2>
      <div class="editor-actions">
        <button class="btn" @click="downloadMarkdown">
          <svg viewBox="0 0 24 24" width="18" height="18">
            <path fill="currentColor" d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" />
          </svg>
          下载
        </button>
        <button class="btn primary" @click="saveContent">
          <svg viewBox="0 0 24 24" width="18" height="18">
            <path fill="currentColor"
              d="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" />
          </svg>
          保存
        </button>
        <button class="btn-icon" @click="toggleTheme">
          <svg viewBox="0 0 24 24" width="18" height="18">
            <path fill="currentColor" v-if="theme === 'light'"
              d="M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5S14.76,7,12,7L12,7z" />
            <path fill="currentColor" v-else
              d="M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36c-0.98,1.37-2.58,2.26-4.4,2.26 c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z" />
          </svg>
        </button>
      </div>
    </div>

    <div class="editor-toolbar">
      <button v-for="tool in tools" :key="tool.action" class="tool-btn" :title="tool.title" @click="insertText(tool)">
        <svg viewBox="0 0 24 24" width="16" height="16">
          <path fill="currentColor" :d="tool.icon" />
        </svg>
      </button>
    </div>

    <div class="split-container">
      <div class="editor-pane">
        <textarea ref="editor" v-model="content" class="markdown-input" placeholder="在此输入 Markdown 内容..."
          @keydown.tab.prevent="handleTab"></textarea>
      </div>

      <div class="preview-pane">
        <div class="markdown-preview" v-html="compiledMarkdown"></div>
      </div>
    </div>

    <div class="editor-footer">
      <div class="footer-info">
        <span>字数: {{ wordCount }}</span>
        <span>行数: {{ lineCount }}</span>
        <span>大小: {{ contentSize }}</span>
      </div>
      <div class="footer-help">
        <button class="btn-icon" @click="showHelp = !showHelp">
          <svg viewBox="0 0 24 24" width="16" height="16">
            <path fill="currentColor"
              d="M11,18H13V16H11V18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,6A4,4 0 0,0 8,10H10A2,2 0 0,1 12,8A2,2 0 0,1 14,10C14,12 11,11.75 11,15H13C13,12.75 16,12.5 16,10A4,4 0 0,0 12,6Z" />
          </svg>
          Markdown 帮助
        </button>
      </div>
    </div>

    <div class="help-modal" v-if="showHelp" @click.self="showHelp = false">
      <div class="help-content">
        <div class="help-header">
          <h3>Markdown 语法参考</h3>
          <button class="btn-icon" @click="showHelp = false">
            <svg viewBox="0 0 24 24" width="20" height="20">
              <path fill="currentColor"
                d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
            </svg>
          </button>
        </div>
        <div class="help-body">
          <table>
            <thead>
              <tr>
                <th>元素</th>
                <th>语法</th>
                <th>示例</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="item in markdownHelp" :key="item.element">
                <td>{{ item.element }}</td>
                <td><code>{{ item.syntax }}</code></td>
                <td>{{ item.example }}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick, defineProps, defineEmits } from 'vue'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import { inject } from 'vue'

const theme = inject("theme", ref('light'))
// 声明要发给父组件的事件
const emit = defineEmits(['save'])
// 编辑器内容
const content = ref(`# Markdown 编辑器

欢迎使用 Markdown 编辑器！以下是一些示例内容：

## 基本语法

- **粗体文本**
- *斜体文本*
- \`行内代码\`

## 列表

1. 有序列表项
2. 第二项
   - 嵌套无序列表
   - 另一个嵌套项

## 代码块

\`\`\`javascript
function hello() {
  console.log('Hello, Markdown!');
}
\`\`\`

## 链接和图片

[示例链接](https://example.com)

![图片描述](https://img.shetu66.com/2023/07/04/1688452147066774.png1)

> 这是一个引用块
`)


// 接收父组件传来的值
const props = defineProps({
  modelValue: {
    type: String,
    default: '' // 父组件不传时默认为空字符串
  }
})
console.log(props.modelValue, 'props.modelValue');

// 如果父组件传了值，则初始化 content
watch(
  () => props.modelValue,
  (newVal) => {
    console.log(newVal !== undefined && newVal !== null && newVal != '');
    if (newVal !== undefined && newVal !== null && newVal != '') {
      content.value = newVal
    }
    // 否则什么都不做，保持原有 content 值
  },
  { immediate: true }
)



const showHelp = ref(false)
const editor = ref(null)

// Markdown 工具
const tools = [
  { action: 'heading1', title: '一级标题', icon: 'M3,4H5V10H9V4H11V18H9V12H5V18H3V4M13,8H15V18H19V8H21V6H13V8Z', syntax: '# 标题' },
  { action: 'heading2', title: '二级标题', icon: 'M3,4H5V10H9V4H11V18H9V12H5V18H3V4M15,6H13V8H15V6M13,18H15V10H13V18M15,10H19V6H15V10M17,8V10H15V8H17M15,18H19V12H15V18M17,16V18H15V16H17Z', syntax: '## 标题' },
  { action: 'bold', title: '粗体', icon: 'M13.5,15.5H10V12.5H13.5A1.5,1.5 0 0,1 15,14A1.5,1.5 0 0,1 13.5,15.5M10,6.5H13A1.5,1.5 0 0,1 14.5,8A1.5,1.5 0 0,1 13,9.5H10M15.6,10.79C16.57,10.11 17.25,9 17.25,8C17.25,5.74 15.5,4 13.25,4H7V18H14.04C16.14,18 17.75,16.3 17.75,14.21C17.75,12.69 16.89,11.39 15.6,10.79Z', syntax: '**粗体**' },
  { action: 'italic', title: '斜体', icon: 'M10,4V7H12.21L8.79,15H6V18H14V15H11.79L15.21,7H18V4H10Z', syntax: '*斜体*' },
  { action: 'link', title: '链接', icon: 'M3.9,12C3.9,10.29 5.29,8.9 7,8.9H11V7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H11V15.1H7C5.29,15.1 3.9,13.71 3.9,12M8,13H16V11H8V13M17,7H13V8.9H17C18.71,8.9 20.1,10.29 20.1,12C20.1,13.71 18.71,15.1 17,15.1H13V17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7Z', syntax: '[文本](url)' },
  { action: 'image', title: '图片', icon: 'M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z', syntax: '![描述](url)' },
  { action: 'quote', title: '引用', icon: 'M14,17H7V15H14M17,13H7V11H17M17,9H7V7H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z', syntax: '> 引用' },
  { action: 'code', title: '行内代码', icon: 'M14.6,16.6L19.2,12L14.6,7.4L16,6L22,12L16,18L14.6,16.6M9.4,16.6L4.8,12L9.4,7.4L8,6L2,12L8,18L9.4,16.6Z', syntax: '`代码`' },
  { action: 'codeBlock', title: '代码块', icon: 'M8,3A2,2 0 0,0 6,5V9A2,2 0 0,1 4,11H3V13H4A2,2 0 0,1 6,15V19A2,2 0 0,0 8,21H10V19H8V14A2,2 0 0,0 6,12A2,2 0 0,0 8,10V5H10V3M16,3A2,2 0 0,1 18,5V9A2,2 0 0,0 20,11H21V13H20A2,2 0 0,0 18,15V19A2,2 0 0,1 16,21H14V19H16V14A2,2 0 0,1 18,12A2,2 0 0,1 16,10V5H14V3H16Z', syntax: '```语言\n代码\n```' },
  { action: 'ul', title: '无序列表', icon: 'M7,5H21V7H7V5M7,13V11H21V13H7M4,4.5A1.5,1.5 0 0,1 5.5,6A1.5,1.5 0 0,1 4,7.5A1.5,1.5 0 0,1 2.5,6A1.5,1.5 0 0,1 4,4.5M4,10.5A1.5,1.5 0 0,1 5.5,12A1.5,1.5 0 0,1 4,13.5A1.5,1.5 0 0,1 2.5,12A1.5,1.5 0 0,1 4,10.5M7,19V17H21V19H7M4,16.5A1.5,1.5 0 0,1 5.5,18A1.5,1.5 0 0,1 4,19.5A1.5,1.5 0 0,1 2.5,18A1.5,1.5 0 0,1 4,16.5Z', syntax: '- 项目' },
  { action: 'ol', title: '有序列表', icon: 'M7,13V11H21V13H7M7,19V17H21V19H7M7,7V5H21V7H7M3,8V5H2V4H4V8H3M2,17V16H5V20H2V19H4V18.5H3V17.5H4V17H2M4.25,10A0.75,0.75 0 0,1 5,10.75C5,10.95 4.92,11.14 4.79,11.27L3.12,13H5V14H2V13.08L4,11H2V10H4.25Z', syntax: '1. 项目' },
  { action: 'hr', title: '分隔线', icon: 'M19,13H5V11H19V13Z', syntax: '---' }
]

const markdownHelp = [
  { element: '标题', syntax: '# H1\n## H2\n### H3', example: '不同级别的标题' },
  { element: '粗体', syntax: '**粗体**', example: '这是**粗体**文本' },
  { element: '斜体', syntax: '*斜体*', example: '这是*斜体*文本' },
  { element: '链接', syntax: '[文本](URL)', example: '[百度](https://www.baidu.com)' },
  { element: '图片', syntax: '![描述](URL)', example: '![图片](https://example.com/image.jpg)' },
  { element: '列表', syntax: '- 无序\n1. 有序', example: '- 项目1\n- 项目2' },
  { element: '引用', syntax: '> 引用内容', example: '> 这是引用内容' },
  { element: '行内代码', syntax: '`代码`', example: '使用`console.log()`' },
  { element: '代码块', syntax: '```语言\n代码\n```', example: '```javascript\nfunction() {}\n```' },
  { element: '分隔线', syntax: '---', example: '上面的内容\n---\n下面的内容' }
]

// 计算属性
const compiledMarkdown = computed(() => {
  return DOMPurify.sanitize(marked(content.value))
})

const wordCount = computed(() => {
  return content.value.trim() ? content.value.trim().split(/\s+/).length : 0
})

const lineCount = computed(() => {
  return content.value.split('\n').length
})

const contentSize = computed(() => {
  const size = new Blob([content.value]).size
  return size > 1024 ? `${(size / 1024).toFixed(1)} KB` : `${size} B`
})

// 方法
const insertText = (tool) => {
  const textarea = editor.value
  const start = textarea.selectionStart
  const end = textarea.selectionEnd
  const selectedText = content.value.substring(start, end)
  let insertText = ''

  switch (tool.action) {
    case 'heading1':
      insertText = `# ${selectedText || '标题'}`
      break
    case 'heading2':
      insertText = `## ${selectedText || '标题'}`
      break
    case 'bold':
      insertText = selectedText ? `**${selectedText}**` : '**粗体文本**'
      break
    case 'italic':
      insertText = selectedText ? `*${selectedText}*` : '*斜体文本*'
      break
    case 'link':
      insertText = selectedText ? `[${selectedText}](URL)` : '[文本](URL)'
      break
    case 'image':
      insertText = selectedText ? `![${selectedText}](URL)` : '![描述](URL)'
      break
    case 'quote':
      insertText = selectedText ? `> ${selectedText.replace(/\n/g, '\n> ')}` : '> 引用内容'
      break
    case 'code':
      insertText = selectedText ? `\`${selectedText}\`` : '`代码`'
      break
    case 'codeBlock':
      insertText = selectedText ? `\`\`\`\n${selectedText}\n\`\`\`` : '```语言\n代码\n```'
      break
    case 'ul':
      insertText = selectedText ? `- ${selectedText.replace(/\n/g, '\n- ')}` : '- 列表项'
      break
    case 'ol':
      insertText = selectedText ? `1. ${selectedText.replace(/\n/g, '\n1. ')}` : '1. 列表项'
      break
    case 'hr':
      insertText = '---'
      break
  }

  content.value = content.value.substring(0, start) + insertText + content.value.substring(end)

  // 设置光标位置
  nextTick(() => {
    let newCursorPos = start + insertText.length

    // 对于某些操作，调整光标位置到内容中间
    if (['bold', 'italic', 'code', 'link', 'image'].includes(tool.action)) {
      if (!selectedText) {
        if (tool.action === 'link' || tool.action === 'image') {
          newCursorPos = start + (tool.action === 'link' ? 1 : 2)
        } else {
          newCursorPos = start + (tool.action === 'code' ? 1 : 2)
        }
      }
    }

    textarea.setSelectionRange(newCursorPos, newCursorPos)
    textarea.focus()
  })
}

const handleTab = (e) => {
  const textarea = e.target
  const start = textarea.selectionStart
  const end = textarea.selectionEnd

  // 插入两个空格
  content.value = content.value.substring(0, start) + '  ' + content.value.substring(end)

  // 移动光标位置
  nextTick(() => {
    textarea.setSelectionRange(start + 2, start + 2)
  })
}
const showMarkdownEditor = ref(false)
const saveContent = () => {
  // 这里添加保存逻辑
  // console.log('保存内容:', content.value)
  emit('save', {
    content: content.value,
    show: showMarkdownEditor.value
  })

  alert('内容已保存')
}

const downloadMarkdown = () => {
  const blob = new Blob([content.value], { type: 'text/markdown' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = 'markdown-content.md'
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

// 初始化 marked.js
marked.setOptions({
  breaks: true,
  gfm: true,
  highlight: (code, lang) => {
    // 实际应用中可以使用 highlight.js 等库
    return code
  }
})
</script>

<style scoped>
.markdown-editor {
  --bg-color: #f8f9fa;
  --text-color: #333;
  --primary-color: #4361ee;
  --secondary-color: #6c757d;
  --border-color: #e1e4e8;
  --card-bg: #fff;
  --hover-bg: #f1f3f5;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: var(--bg-color);
  color: var(--text-color);
  transition: all 0.3s ease;
}

.markdown-editor.dark {
  --bg-color: #1a1a1a;
  --text-color: #e0e0e0;
  --primary-color: #4895ef;
  --secondary-color: #8e8e8e;
  --border-color: #333;
  --card-bg: #2d2d2d;
  --hover-bg: #383838;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

.editor-header {
  padding: 0.8rem 1.5rem;
  background-color: var(--card-bg);
  box-shadow: var(--shadow);
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border-color);
}

.editor-header h2 {
  margin: 0;
  font-size: 1.25rem;
}

.editor-actions {
  display: flex;
  gap: 0.8rem;
  align-items: center;
}

.btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.2s ease;
  border: 1px solid var(--border-color);
  background-color: var(--card-bg);
  color: var(--text-color);
}

.btn:hover {
  background-color: var(--hover-bg);
}

.btn.primary {
  background-color: var(--primary-color);
  color: white;
  border-color: var(--primary-color);
}

.btn.primary:hover {
  opacity: 0.9;
}

.btn-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
  background-color: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: 4px;
  color: var(--text-color);
  cursor: pointer;
  transition: all 0.2s ease;
}

.btn-icon:hover {
  background-color: var(--hover-bg);
}

.editor-toolbar {
  padding: 0.5rem 1rem;
  background-color: var(--card-bg);
  border-bottom: 1px solid var(--border-color);
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.tool-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 4px;
  background-color: var(--card-bg);
  border: 1px solid var(--border-color);
  color: var(--text-color);
  cursor: pointer;
  transition: all 0.2s ease;
}

.tool-btn:hover {
  background-color: var(--hover-bg);
  color: var(--primary-color);
}

.split-container {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.editor-pane,
.preview-pane {
  flex: 1;
  overflow: auto;
  position: relative;
}

.editor-pane {
  border-right: 1px solid var(--border-color);
}

.markdown-input {
  width: 100%;
  height: 100%;
  padding: 2rem;
  border: none;
  resize: none;
  font-family: 'Courier New', Courier, monospace;
  line-height: 1.6;
  background-color: var(--card-bg);
  color: var(--text-color);
  tab-size: 2;
  scrollbar-width: thin;
  font-size: medium;
  /* 对于Firefox */
  scrollbar-color: var(--secondary-color) var(--hover-bg);
  /* 对于Firefox */
}

.markdown-input:focus {
  outline: none;
}

/* Webkit浏览器(Chrome, Safari, Edge)的滚动条样式 */
.markdown-input::-webkit-scrollbar {
  width: 20px;
  height: 8px;
}

.markdown-input::-webkit-scrollbar-track {
  background-color: var(--hover-bg);
  border-radius: 4px;
}

.markdown-input::-webkit-scrollbar-thumb {
  background-color: var(--secondary-color);
  border-radius: 4px;
}

.markdown-input::-webkit-scrollbar-thumb:hover {
  background-color: var(--primary-color);
}

/* 对于Firefox的滚动条样式 */
@supports (scrollbar-color: red blue) {
  .markdown-input {
    scrollbar-color: var(--secondary-color) var(--hover-bg);
    scrollbar-width: thin;
  }
}

.markdown-preview {
  padding: 1rem;
  height: 100%;
  box-sizing: border-box;
  overflow-y: auto;
  background-color: var(--card-bg);
}

.editor-footer {
  padding: 0.8rem 1.5rem;
  background-color: var(--card-bg);
  border-top: 1px solid var(--border-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.85rem;
  color: var(--secondary-color);
}

.footer-info {
  display: flex;
  gap: 1rem;
}

.help-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.help-content {
  background-color: var(--card-bg);
  border-radius: 8px;
  width: 100%;
  max-width: 800px;
  max-height: 80vh;
  overflow: hidden;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
}

.help-header {
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--border-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.help-header h3 {
  margin: 0;
  font-size: 1.1rem;
}

.help-body {
  padding: 1rem;
  overflow-y: auto;
}

.help-body table {
  width: 100%;
  border-collapse: collapse;
}

.help-body th,
.help-body td {
  padding: 0.8rem;
  text-align: left;
  border-bottom: 1px solid var(--border-color);
}

.help-body th {
  font-weight: 500;
  background-color: var(--hover-bg);
}

.help-body code {
  background-color: var(--hover-bg);
  padding: 0.2rem 0.4rem;
  border-radius: 4px;
  font-family: monospace;
}

/* Markdown 预览样式 */
.markdown-preview h1,
.markdown-preview h2,
.markdown-preview h3,
.markdown-preview h4,
.markdown-preview h5,
.markdown-preview h6 {
  margin-top: 1.5em;
  margin-bottom: 0.8em;
  font-weight: 600;
  color: var(--text-color);
}

.markdown-preview h1 {
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 0.3em;
}

.markdown-preview p {
  margin-bottom: 1em;
  line-height: 1.6;
}

.markdown-preview a {
  color: var(--primary-color);
  text-decoration: none;
}

.markdown-preview a:hover {
  text-decoration: underline;
}

.markdown-preview ul,
.markdown-preview ol {
  margin-bottom: 1em;
  padding-left: 2em;
}

.markdown-preview li {
  margin-bottom: 0.5em;
}

.markdown-preview blockquote {
  margin: 1em 0;
  padding: 0 1em;
  border-left: 4px solid var(--primary-color);
  color: var(--secondary-color);
}

.markdown-preview pre {
  background-color: var(--hover-bg);
  padding: 1em;
  border-radius: 6px;
  overflow-x: auto;
  margin-bottom: 1em;
}

.markdown-preview code {
  font-family: 'Courier New', Courier, monospace;
  background-color: var(--hover-bg);
  padding: 0.2em 0.4em;
  border-radius: 4px;
}

.markdown-preview img {
  max-width: 100%;
  border-radius: 4px;
}

.markdown-preview hr {
  border: none;
  border-top: 1px solid var(--border-color);
  margin: 1.5em 0;
}

/* 分割条样式 */
.split-container {
  position: relative;
}

.split-container::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background-color: var(--border-color);
  z-index: 1;
}

@media (max-width: 1200px) {
  .split-container {
    flex-direction: column;
  }

  .split-container::after {
    display: none;
  }

  .editor-pane,
  .preview-pane {
    height: 50%;
  }

  .editor-pane {
    border-right: none;
    border-bottom: 1px solid var(--border-color);
  }
}

@media (max-width: 768px) {
  .editor-actions {
    gap: 0.5rem;
  }

  .btn span {
    display: none;
  }

  .btn svg {
    margin-right: 0;
  }

  .help-content {
    max-width: 95%;
    max-height: 90vh;
  }

  .help-body table {
    display: block;
    overflow-x: auto;
  }

  .footer-info {
    flex-direction: column;
    gap: 0.3rem;
  }
}
</style>